﻿using Cysharp.Threading.Tasks;
using Factory;
using Logic;
using Services;
using Services.Input;
using Services.Loot;
using Services.Progress;
using Services.StaticData;
using Services.Window;

namespace Infrastructure.States
{
    public class BootstrapState : IState
    {
        private readonly GameStateMachine _stateMachine;
        private readonly SceneLoader _sceneLoader;
        private readonly AllServices _services;

        public BootstrapState(GameStateMachine stateMachine, SceneLoader sceneLoader, AllServices services)
        {
            _stateMachine = stateMachine;
            _sceneLoader = sceneLoader;
            _services = services;
            RegisterServices();
        }

        public void Enter() =>
            _sceneLoader.Load(Constants.Initial, EnterLoadProgress).Forget();

        public void Exit()
        {
            
        }

        private void RegisterServices()
        {
            RegisterStaticData();
            _services.RegisterSingle<IInputService>(new InputService());
            _services.RegisterSingle<IProgressService>(new ProgressService());
            _services.RegisterSingle<ILootFactory>(new LootFactory(
                    _services.Single<IProgressService>(),
                    _stateMachine,
                    _services.Single<IStaticDataService>()));
            _services.RegisterSingle<ILootService>(new LootService(
                _services.Single<ILootFactory>(),
                _services.Single<IProgressService>()));
            _services.RegisterSingle<IGameFactory>(new GameFactory(
                    _services.Single<IProgressService>(),
                    _services.Single<ILootService>(),
                    _services.Single<IStaticDataService>(),
                    _services.Single<IInputService>(),
                    _stateMachine));
            _services.RegisterSingle<IUiFactory>(new UiFactory(
                _services.Single<IProgressService>(),
                _stateMachine, 
                _services.Single<IStaticDataService>()));
            _services.RegisterSingle<IWindowService>(new WindowService(
                _services.Single<IUiFactory>()));
        }

        private void RegisterStaticData()
        {
            IStaticDataService staticData = new StaticDataService();
            staticData.Load();
            _services.RegisterSingle(staticData);
        }

        private void EnterLoadProgress() =>
            _stateMachine.Enter<LoadProgressState>();
    }
}